﻿using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;

namespace spSitePro.TagCloudWP.TagCloudWebPart
{
	[ToolboxItemAttribute(false)]
	public class TagCloudWebPart : WebPart
	{
		#region [Constants]

		private const string AscxPath = @"~/_CONTROLTEMPLATES/spSitePro.TagCloudWP/TagCloudWebPartUserControl.ascx";
		private const string WebServiceUrlFormat = "{0}_layouts/spSitePro.TagCloudWP/TagCloudHandler.ashx?{1}={2}&{3}={4}&{5}={6}&{7}={8}&{9}={10}&{11}={12}&{13}={14}";

		#endregion

		#region [Properties]

		[LocalizedWebDisplayName("Term Store Name")]
		[Category("Managed Metadata Properties")]
		[Personalizable(PersonalizationScope.Shared)]
		[WebBrowsable(true)]
		public string TermStoreName { get; set; }

		[WebDisplayName("Group Name")]
		[Category("Managed Metadata Properties")]
		[Personalizable(PersonalizationScope.Shared)]
		[WebBrowsable(true)]
		public string TermSetGroupName { get; set; }

		[WebDisplayName("Term Set Name")]
		[Category("Managed Metadata Properties")]
		[Personalizable(PersonalizationScope.Shared)]
		[WebBrowsable(true)]
		public string TermSetName { get; set; }

		[WebDisplayName("Term Managed Property Name")]
		[Category("Search Services Properties")]
		[Personalizable(PersonalizationScope.Shared)]
		[WebBrowsable(true)]
		public string SearchManagedPropertyName { get; set; }

		[WebDisplayName("Number of Tags to display")]
		[Category("Tag Cloud Properties")]
		[Personalizable(PersonalizationScope.Shared)]
		[WebBrowsable(true)]
		public int TagCount { get; set; }

		[WebDisplayName("Redirect Url Format")]
		[Category("Tag Cloud Properties")]
		[Personalizable(PersonalizationScope.Shared)]
		[WebBrowsable(true)]
		public string RedirectUrlFormat { get; set; }

		[WebDisplayName("Tool Tip Format")]
		[Category("Tag Cloud Properties")]
		[Personalizable(PersonalizationScope.Shared)]
		[WebBrowsable(true)]
		public string ToolTipFormat { get; set; }

		[WebDisplayName("Use Caching")]
		[Category("Cache")]
		[Personalizable(PersonalizationScope.Shared)]
		[WebBrowsable(true)]
		public bool UseCaching { get; set; }

		[WebDisplayName("Cache Interval, min")]
		[Category("Cache")]
		[Description("Interval the data is cached. Used only if UseCaching checked.")]
		[Personalizable(PersonalizationScope.Shared)]
		[WebBrowsable(true)]
		public int CacheInterval { get; set; }

		#endregion

		#region [Constructor]

		public TagCloudWebPart()
		{
			TagCount = 10;
			RedirectUrlFormat = "/Search/Pages/Results.aspx?k=tags:{0}";
			ToolTipFormat = "Tagged items: {0}";
			UseCaching = true;
			CacheInterval = 15;
		}

		#endregion

		protected override void CreateChildControls()
		{
			if (string.IsNullOrEmpty(TermStoreName) || string.IsNullOrEmpty(TermSetName) ||
				string.IsNullOrEmpty(TermSetGroupName) || string.IsNullOrEmpty(SearchManagedPropertyName))
			{
				HandleErrorMessage("'Term Store Name', 'Term Group Name', 'Term Set Name' and 'Tags Search Managed Property Name' should not be empty. Please provide correct values.", "");
				return;
			}

			try
			{
				string requestUrl = string.Format(WebServiceUrlFormat,
													AppendSlashToEnd(SPContext.Current.Web.ServerRelativeUrl),
													C.RequestParams.TagCount, TagCount,
													C.RequestParams.RedirectUrlFormat, HttpUtility.UrlEncode(RedirectUrlFormat),
													C.RequestParams.TagToolTipFormat, HttpUtility.UrlEncode(ToolTipFormat),
													C.RequestParams.TermStoreName, TermStoreName,
													C.RequestParams.TermSetGroupName, TermSetGroupName,
													C.RequestParams.TermSetName, TermSetName,
													C.RequestParams.SearchManagedPropertyName, SearchManagedPropertyName);

				TagCloudWebPartUserControl control = (TagCloudWebPartUserControl)Page.LoadControl(AscxPath);
				control.RequestUrl = requestUrl;
				Controls.Add(control);
			}
			catch (Exception ex)
			{
				HandleException(ex);
			}
		}

		#region [Helper Methods]

		private void HandleErrorMessage(string errorMessage, string errorInfo)
		{
			string messageHtml = SPContext.Current.Web.UserIsWebAdmin || SPContext.Current.Web.UserIsSiteAdmin
									? string.Format(
													"<div class=\"webpart-err\"><span>{0}</span><br/><span>{1}</span></div>",
													errorMessage,
													errorInfo)
									: "<div class=\"webpart-err\">Unexpected error has occurred. Please contact your administrator.</div>";
			Controls.Add(new LiteralControl(messageHtml));
		}

		private void HandleException(Exception ex)
		{
			HandleErrorMessage(ex.Message, ex.Message);
		}

		private string AppendSlashToEnd(string relativeUrl)
		{
			if (!string.IsNullOrEmpty(relativeUrl))
			{
				if (relativeUrl[relativeUrl.Length - 1] != '/')
				{
					return relativeUrl + '/';
				}
			}

			return relativeUrl;
		}

		#endregion
	}
}
